package com.its.us.web.service.sys;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.its.us.web.entity.sys.Menu;
import com.its.us.web.entity.sys.Role;
import com.its.us.web.entity.sys.User;
import com.its.us.web.mapper.sys.MenuMapper;
import com.its.us.web.mapper.sys.RoleMapper;
import com.its.us.web.mapper.sys.UserMapper;
import com.its.us.web.utils.JwtTokenUtil;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * security user detail's service impl
 * @className UserDetailsServiceImpl
 * @author huguangjun
 * @date 2020/12/3
 * @desc 9:06
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private MenuMapper menuMapper;

    //@Autowired
    //private PasswordEncoder passwordEncoder;

    public User getUserByName(String username) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("username", username);
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return getUserDetails(username, true);
    }

    public UserDetails getUserDetails(String username, boolean hasPassword) {
        User user;
        if (hasPassword) {
            user = this.getUserByName(username);
        } else {
            user = userMapper.getUserByNameNotPassword(username);
        }
        if (user == null) {
            throw new UsernameNotFoundException(String.format("用户名为 %s 的用户不存在！", user.getUsername()));
        } else {
            StringBuffer sb = new StringBuffer();
            try {
                List<Role> roles = roleMapper.getCurrentRoles(username);
                List<Menu> menus = menuMapper.getCurrentMenus(username);
                if (roles.size() > 0) {
                    List<String> roleEn = roles.stream().map(Role::getRoleEn).filter(s -> s != null).collect(Collectors.toList());
                    roleEn.forEach(s -> sb.append("ROLE_" + s + ","));
                }
                if (menus.size() > 0) {
                    List<String> permission = menus.stream().map(Menu::getPermission).filter(s -> s != null).collect(Collectors.toList());
                    permission.forEach(s -> sb.append(s + ","));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            String authorities = sb.deleteCharAt(sb.length() - 1).toString();
            // get db's password already encoder
            return new User(user.getId(), username, user.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList(authorities), user.getIsEnabled());
        }
    }


}
